/**
 * File comment: completed both login and register
 */
package edu.gatech.oad.project.networking.serverSessions; // $codepro.audit.disable packageNamingConvention

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

import edu.gatech.oad.project.coordinator.Office;
import edu.gatech.oad.project.operations.users.Doctor;
import edu.gatech.oad.project.operations.users.Nurse;
import edu.gatech.oad.project.operations.users.Patient;
import edu.gatech.oad.project.operations.users.SystemAdmin;
import edu.gatech.oad.project.operations.users.User;

//$codepro.audit.disable numericLiterals

/**
 * Represents the preliminary connection before a true
 * session is make
 * 
 * @author James Moore
 * @version 1.0
 */
public class loginSessionServer implements Runnable{ // $codepro.audit.disable classNamingConvention
    
    /**
     * Field client: connection to the client
     */
    private final Socket client;

    /**
     * Field myLogger: holds the logger for the office file
     */
    private static final Logger MYLOGGER = Logger.getLogger("edu.gatech." +
            "oad.project.networking.serverSessions");
    
    /**
     * Default constructor
     * 
     * @param client the connection to the client
     */
    public loginSessionServer(Socket client) {
        this.client = client;
        
        MYLOGGER.addHandler(Office.FILEHANDLER);
        MYLOGGER.setLevel(Level.ALL);
    }
    
    /**
     * Executes when the thread is started
     */
    @Override
    public void run() {
        try {
            ObjectInputStream  inBound = null;
            ObjectOutputStream outBound = null;
             
            outBound = new ObjectOutputStream(client.getOutputStream()); // $codepro.audit.disable closeWhereCreated
            outBound.flush();
            inBound = new ObjectInputStream(client.getInputStream()); // $codepro.audit.disable closeWhereCreated
            String method = "nothing";
            String username = "nothing";
            String pass = "nothing";
            try {
                method = (String) inBound.readUnshared();
                username = (String) inBound.readUnshared();
                pass = (String) inBound.readUnshared();
                
            } catch (ClassNotFoundException e) {
                MYLOGGER.severe("" + e);
            }
            final int offset = 3; 
            String[] data = new String[offset];
            data[0] = "";
            if (method.equals("login")) {
                data = Office.CONVERTER.login(username, pass);
            
                if (!data[0].equals("")) {
                    outBound.writeUnshared(new String(data[0]));
                    outBound.writeUnshared(new String(data[1]));
                    outBound.writeUnshared(new String(data[2]));
                    outBound.flush();
                }
                
                Thread thr = null;
                if(data[0].equals("true")) {
                    final long token = Office.RAND.nextLong();
                    User temp;
                    
                    if (data[2].equals("nurse")) {
                        temp = new Nurse("lol", 3);
                        thr = new Thread(new NurseSession((Nurse) temp, 
                                token, client, outBound, inBound), Long.toString(token));
                    }
                    else if (data[2].equals("doctor")) {
                        temp = new Doctor("lol", 2);
                        thr = new Thread(new DoctorSession((Doctor) temp, 
                                token, client, outBound, inBound), Long.toString(token));
                    }
                    else if (data[2].equals("admin")) {
                        temp = new SystemAdmin("lol", 1);
                        thr = new Thread(new AdminSession((SystemAdmin) temp, 
                                token, client, outBound, inBound), Long.toString(token));
                    }
                    else {
                        temp = new Patient("lol", 4);
                        thr = new Thread(new PatientSession((Patient) temp, 
                                token, client, outBound, inBound), Long.toString(token));
                    } 
                    System.out.println(token);
                    outBound.writeUnshared(new Long(token));
                    outBound.writeUnshared(temp);
                    outBound.flush();
                    
                    Office.POOL.execute(thr);
                }
            }
            else if (method.equals("register")) {
                try {
                    
                    final String rank = (String) inBound.readUnshared();
                    final Boolean response = Office.CONVERTER.canRegister(username, 
                            pass, rank);                    
                    outBound.writeUnshared(response);
                    outBound.flush();
                    
                } catch (ClassNotFoundException e) {
                    MYLOGGER.severe("" + e);
                }
            }
            
        }
        catch(IOException e){
            System.out.println("lol server fail" + e);
        } 
    }

    /**
     * @return a string
     */
    @Override
    public String toString() {
        return "loginSessionServer [client=" + client + "]";
    }
    
    
}
